package aiku.numericalcontroloa.Service.Impl;

import aiku.numericalcontroloa.Base.Utils.HttpStatus;
import aiku.numericalcontroloa.Base.Utils.Result;
import aiku.numericalcontroloa.Mapper.*;
import aiku.numericalcontroloa.Model.Dto.DevicesDto;
import aiku.numericalcontroloa.Model.Dto.DevicesPartVo;
import aiku.numericalcontroloa.Model.Entity.*;
import aiku.numericalcontroloa.Model.Vo.*;
import aiku.numericalcontroloa.Task.NormalTask;
import aiku.numericalcontroloa.enums.RoleEnum;
import cn.dev33.satoken.stp.StpUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import aiku.numericalcontroloa.Service.DevicesService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 马
 * @description 针对表【devices】的数据库操作Service实现
 * @createDate 2024-02-26 15:22:30
 */
@Service
public class DevicesServiceImpl extends ServiceImpl<DevicesMapper, Devices>
        implements DevicesService {
    @Autowired
    private DevicesMapper devicesMapper;
    @Autowired
    private DevicesOutboundMapper devicesOutboundMapper;
    @Autowired
    private DevicesReturnMapper devicesReturnMapper;
    @Autowired
    private ProductPartMapper productPartMapper;
    @Autowired
    private CurrentMapper currentMapper;
    @Autowired
    private PurchaseReceiptsMapper purchaseReceiptsMapper;
    @Autowired
    private ProductPartServiceImpl productPartService;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private NormalTask normalTask;

    /**
     * 根据名称查询仓库已有产品信息
     * 
     * @return
     */
    @Override
    public Result selectName(String name) {
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Devices::getPartName, name);
        List<Devices> devicesList = devicesMapper.selectList(queryWrapper);
        return Result.success(devicesList);
    }

    /**
     * 分页查询,查询仓库所有产品信息并且返回
     * 
     * @param page
     * @param size
     * @return
     */
    @Override
    public Result selectList(Integer page, Integer size, String status) {
        // TODO 权限还未验证
        Page<Devices> pages = new Page<>(page, size);
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        if (!status.equals("-1") && status != null) {
            queryWrapper.eq(Devices::getIsProduct, status);
        }
        // 根据数量越多排在前
        queryWrapper.orderByDesc(Devices::getCount);
        // 所有库存产品信息
        List<Devices> devicesList2 = devicesMapper.selectPage(pages, queryWrapper).getRecords();
        if (devicesList2.size() == 0) {
            return Result.success(new DevicesPageVo2());
        }
        // 取出devicesList2中isProduct为0的List
        List<Devices> devicesList = devicesList2.stream().filter(devices -> devices.getIsProduct().equals("0"))
                .collect(Collectors.toList());
        List<Devices> devicesList1 = devicesList2.stream().filter(devices -> devices.getIsProduct().equals("1"))
                .collect(Collectors.toList());

        List<DevicesInfoVo> arrayList = new ArrayList<>();

        // 查询每个成品最多能组装的数量
        /**
         * 先拿到所有产品id,通过产品id去零件关系表中,查询零件信息,可能有的产品没有零件信息,
         * 所以需要判断,如果没有零件信息的产品一律认为是0,这个时候会一个产品出现多个零件id,
         * 拿到零件id之后,查询这些零件信息,然后通过零件信息中的产品id去查询这个零件在仓库中的数量,
         * 然后通过仓库中的数量来进行计算,把该产品仓库中的数量除以所需零件数量,得到最大组装数量,值最小的那个就是最大组装数量,
         * 然后封装VO给前端
         */
        if (devicesList.size() > 0) {
            // 仓库产品id
            List<String> devicesIdList = devicesList.stream().map(Devices::getId).collect(Collectors.toList());
            // 通过仓库产品id去零件关系表中,查询零件信息,这是全部产品的相关零件信息
            List<ProductPart> productPartList = productPartMapper
                    .selectList(new LambdaQueryWrapper<ProductPart>().in(ProductPart::getDevicesId, devicesIdList));
            if (productPartList.isEmpty()) {
                return Result.success(new DevicesPageVo2());
            }
            // 存入map防止循环性能问题
            // Map<String, ProductPart> productPartMap =
            // productPartList.stream().collect(Collectors.toMap(ProductPart::getPartId,
            // Function.identity()));
            // 拿出零件在仓库中的id去查询零件在仓库中的数量
            List<String> partIdList = productPartList.stream().map(ProductPart::getPartId).collect(Collectors.toList());
            // 去仓库查询零件信息
            List<Devices> devicesListTow = devicesMapper
                    .selectList(new LambdaQueryWrapper<Devices>().in(Devices::getId, partIdList));
            Map<String, Devices> devicesMap = devicesListTow.stream()
                    .collect(Collectors.toMap(Devices::getId, Function.identity()));

            /**
             * 通过遍历仓库零件信息,用信息中的id去productPartMap中查找所需数量,通过所需数量去计算最大组装数量
             * 方法2
             * 通过最开始的产品信息直接循环,通过产品id去productPartList中找对应的零件id,通过零件id再去devicesMap中拿到数据,进行比较即可
             *
             */
            for (Devices devices : devicesList) {
                // 根据产品id去零件关系表中,查询零件信息
                Map<Object, Integer> mapOne = new HashMap<>();
                // 该产品和零件的总价格
                BigDecimal price = new BigDecimal("0");
                // 最多组装数量
                Integer min = Integer.MAX_VALUE;
                // 所以零件所需数量
                Float number = 0.0f;
                for (ProductPart productPart : productPartList) {
                    // 仓库产品id和零件绑定的产品id一致
                    if (devices.getId().equals(productPart.getDevicesId())) {
                        number += productPart.getNumber();
                        // 再通过零件信息中零件在仓库的id去devicesListTow仓库中查询信息
                        Devices devOne = devicesMap.get(productPart.getPartId());
                        // 使用产品数量除零件数量然后存入map,这就是当前零件能组装的数量
                        Integer sus = (int) ((devOne.getCount() / productPart.getNumber()));
                        // 该零件的价格,仓库价格*零件需要数量
                        price = price.add(devOne.getPrice().multiply(new BigDecimal(productPart.getNumber())));
                        mapOne.put(productPart.getPartId(), sus);
                    }
                }

                for (Map.Entry<Object, Integer> entry : mapOne.entrySet()) {
                    if (entry.getValue() < min) {
                        min = entry.getValue();
                    }
                }

                // 用仓库减去最小的数*所需的数,然后判断各个零件仓库是否大于需求,如果够,那么就把需求数加进去,如果不够,就把剩下加进去,最后计算出最后一个产品组装到百分之多少,
                double ride = 100.0 / number;
                Float sums = 0.0f;
                for (ProductPart productPart : productPartList) {
                    // 仓库产品id和零件绑定的产品id一致
                    if (devices.getId().equals(productPart.getDevicesId())) {
                        // 再通过零件信息中零件在仓库的id去devicesListTow仓库中查询信息
                        Devices devOne = devicesMap.get(productPart.getPartId());
                        // 这个是剩余的库存
                        Integer sus = (int) (devOne.getCount() - productPart.getNumber() * min);
                        if (sus >= productPart.getNumber()) {
                            sums += productPart.getNumber();
                        } else {
                            sums += sus;
                        }
                        // 该零件的价格,仓库价格*零件需要数量
                        price = price.add(devOne.getPrice().multiply(new BigDecimal(productPart.getNumber())));
                        mapOne.put(productPart.getPartId(), sus);
                    }
                }
                Current current = currentMapper.selectById("1");
                System.out.println("=========================================" + ride * sums);
                if (ride * sums >= current.getCourt()) {
                    min += 1;
                }

                // 拿出最小组装数,然后计算出最后一个产品组装到百分之多少,
                DevicesInfoVo infoVo = new DevicesInfoVo();
                BeanUtils.copyProperties(devices, infoVo);
                infoVo.setMaxPrice(price);
                infoVo.setMaxCount(min);
                arrayList.add(infoVo);
            }

            /**
             * 计算出该产品零件组合
             */

        }

        if (devicesList1.size() > 0) {
            for (Devices devices : devicesList1) {
                DevicesInfoVo infoVo = new DevicesInfoVo();
                BeanUtils.copyProperties(devices, infoVo);
                arrayList.add(infoVo);
            }
        }

        Long count = devicesMapper.selectCount(queryWrapper);
        DevicesPageVo2 devicesPageVo2 = new DevicesPageVo2();
        devicesPageVo2.setDevicesInfoVoList(arrayList);
        devicesPageVo2.setTotal(count);
        return Result.success(devicesPageVo2);
    }

    /**
     * 管理员审核用户归还产品
     * 
     * @param returnId
     * @param status
     * @return
     */
    @Override
    public Result adminCheckReturn(String returnId, String status) {
        // 先查询是否借出该产品
        DevicesReturn devicesReturn = devicesReturnMapper.selectById(returnId);
        if (devicesReturn == null) {
            return Result.error("没有借出记录");
        }
        // 审核通过,就往产品里面加数量
        if (status.equals("0")) {
            // 拿借出id去申请出库表中拿到数据
            LambdaQueryWrapper<DevicesOutbound> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(DevicesOutbound::getReturnId, returnId);
            DevicesOutbound devicesOutbound = devicesOutboundMapper.selectOne(wrapper);
            if (devicesOutbound == null) {
                return Result.error("出库订单不存在");
            }
            // 拿到设备id，修改设备数量
            Devices devices = devicesMapper.selectById(devicesOutbound.getDevicesId());
            if (devices == null) {
                return Result.error("产品不存在");
            }
            // 修改数量
            devices.setCount(devices.getCount() + devicesOutbound.getCount());
            devicesMapper.updateById(devices);
        }
        devicesReturn.setReturnStatus(status);
        devicesReturnMapper.updateById(devicesReturn);
        return Result.success("操作成功");
    }

    /**
     * 模糊查询
     * 
     * @param name
     * @return
     */
    @Override
    public Result selectLike(String name) {
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(Devices::getPartName, name).or().like(Devices::getModel, name);
        List<Devices> devicesList = devicesMapper.selectList(queryWrapper);

        DevicesPageVo devicesPageVo = new DevicesPageVo();
        devicesPageVo.setDevicesVoList(devicesList);
        devicesPageVo.setTotal(Long.valueOf(devicesList.size()));
        return Result.success(devicesPageVo);
    }

    /**
     * 模糊查询产品名称型号
     * 
     * @param name
     * @return
     */
    @Override
    public Result selectPartLike(String name) {
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        // 1是零件
        queryWrapper.eq(Devices::getIsProduct, "1").like(Devices::getPartName, name).or().like(Devices::getModel, name);
        List<Devices> devicesList = devicesMapper.selectList(queryWrapper);
        return Result.success(devicesList);
    }

    /**
     * 查询仓库所有配件
     * 
     * @return
     */
    @Override
    public Result selectPartList() {
        // TODO 权限还未验证
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Devices::getIsProduct, "1");
        // 根据数量越多排在前
        queryWrapper.orderByDesc(Devices::getCount);
        List<Devices> devicesList = devicesMapper.selectList(queryWrapper);
        return Result.success(devicesList);
    }

    /**
     * 仓库新增产品，而不是零件
     * 
     * @param
     * @return
     */
    @Override
    public Result addProductIs(DevicesPartVo devicesPartVo) {
        Devices devices = new Devices();
        BeanUtils.copyProperties(devicesPartVo, devices);
        // TODO 权限还未做
        // 通过名称,型号来查询仓库是否有改产品,如果存在,提醒用户
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Devices::getPartName, devices.getPartName());
        queryWrapper.eq(Devices::getModel, devices.getModel());
        Devices one = devicesMapper.selectOne(queryWrapper);
        if (one != null) {
            return Result.error(201, "该产品已存在,请勿重复添加");
        }
        // 不存在则添加产品到仓库
        devices.setCount(0.0f);
        // 设置为产品
        devices.setIsProduct(0);
        // 仓库类型(1月结供库,2现金库,3其他库,4生产用品库,5成品库)
        devices.setWarehouseType("5");
        int i = devicesMapper.insert(devices);
        // 添加产品零件到仓库
        for (ProductPart part : devicesPartVo.getPart()) {
            part.setDevicesId(devices.getId());
        }
        productPartService.saveBatch(devicesPartVo.getPart());
        return i > 0 ? Result.success("新增成功") : Result.error(201, "新增失败");
    }

    /**
     * 查询百分比给前端
     * 
     * @return
     */
    @Override
    public Result selectPercent() {
        Current current = currentMapper.selectById("1");
        return Result.success(current.getCourt());
    }

    /**
     * 修改百分比
     * 
     * @param percent
     * @return
     */
    @Override
    public Result updatePercent(Integer percent) {
        Current current = new Current();
        current.setCourt(percent);
        LambdaQueryWrapper<Current> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Current::getId, "1");
        currentMapper.update(current, queryWrapper);
        return Result.success("修改成功");
    }

    /**
     * 管理员修改产品
     * 
     * @param devices
     * @return
     */
    @Override
    public Result adminUpdateDevice(Devices devices) {
        // TODO 权限还未做
        int id = devicesMapper.updateById(devices);
        if (id > 0) {
            return Result.success("保存成功");
        }
        return Result.error(201, "保存失败");
    }

    /**
     * 分页查询出入库单分析报表
     * 
     * @param page
     * @param size
     * @return BillingReportVo
     */
    @Override
    public Result selectOutboundList(Integer page, Integer size) {
        // 还未做权限
        // 分页查询所有入库订单信息
        Page<PurchaseReceipts> pages = new Page<>(page, size);
        LambdaQueryWrapper<PurchaseReceipts> queryWrapper = new LambdaQueryWrapper<>();
        // 入库状态是已入库,并且是零件
        queryWrapper.eq(PurchaseReceipts::getReceiptsStatus, "0");
        queryWrapper.eq(PurchaseReceipts::getIsProduct, "1");
        List<PurchaseReceipts> receiptsList = purchaseReceiptsMapper.selectPage(pages, queryWrapper).getRecords();
        // 然后拿出所有产品id,并且去重
        if (receiptsList.size() <= 0) {
            return Result.success(new BillingReportPageVo());
        }
        List<String> devicesIdList = receiptsList.stream().map(PurchaseReceipts::getWarehouseDevId)
                .collect(Collectors.toList());
        // 去重
        devicesIdList = devicesIdList.stream().distinct().collect(Collectors.toList());
        // 零件信息
        List<Devices> devicesList = devicesMapper.selectBatchIds(devicesIdList);
        List<String> strings = devicesList.stream().map(Devices::getId).collect(Collectors.toList());
        // TODO 通过零件id去查询零件产品表 (可能出现的问题是这个零件id,产品表中并没有出库)
        // 拿零件id去查询出库单
        // (还有一个问题没有考虑,这个产品可能有多次出库,多次出库价格如果不一样,应该把所以相同产品,数量*价格,然后求和,得出当前产品出库收益)
        LambdaQueryWrapper<DevicesOutbound> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DevicesOutbound::getStatus, 0);
        wrapper.in(DevicesOutbound::getDevicesId, strings);
        // 查询到的出库记录表
        List<DevicesOutbound> devicesOutbounds = devicesOutboundMapper.selectList(wrapper);
        // 通过产品去查询出库单
        List<BillingReportVo> billingReportVoList = new ArrayList<>();
        for (Devices devices : devicesList) {
            BillingReportVo reportVo = new BillingReportVo();
            reportVo.setTwoCount(0.0f);
            reportVo.setPartName(devices.getPartName());
            reportVo.setOnePrice(new BigDecimal("0"));
            reportVo.setOneCount(0.0f);
            // 入库价格
            BigDecimal twosPrice2 = new BigDecimal("0");
            Float ley2 = 0.0f;
            for (PurchaseReceipts receipts : receiptsList) {
                if (devices.getId().equals(receipts.getWarehouseDevId())) {
                    // 计算平均入库价格
                    // 产品相同,则开始计算入库价格,出库价格,入库数量,出库数量,利润计算,直接把产品现价当做入库价
                    ley2 = ley2 + receipts.getNumber();
                    // 出库平均价
                    // reportVo.setTwoPrice(outbound.getPrice());
                    reportVo.setOnePrice(reportVo.getOnePrice()
                            .add(receipts.getPrice().multiply(new BigDecimal(receipts.getNumber()))));
                    reportVo.setOneCount(reportVo.getOneCount() + receipts.getNumber());
                    // 无障碍悬浮打开之后,点击软件会直接退出,退出的时候马上再次点击软件就可以了
                }
            }
            // 使用价格除以ley
            if (ley2 > 0) {
                reportVo.setOnePrice(reportVo.getOnePrice().divide(new BigDecimal(ley2), 2, RoundingMode.HALF_UP));
            }

            reportVo.setDevicesId(devices.getId());
            reportVo.setModel(devices.getModel());
            reportVo.setImage(devices.getImage());
            // BigDecimal onesPrice = devices.getPrice().multiply(new
            // BigDecimal(devices.getCount()));
            BigDecimal onesPrice = reportVo.getOnePrice().multiply(new BigDecimal(reportVo.getOneCount()));
            BigDecimal twosPrice = new BigDecimal("0");
            reportVo.setTwoPrice(twosPrice);
            Float ley = 0.0f;
            for (DevicesOutbound outbound : devicesOutbounds) {
                // 如果一样那么就是同一个产品
                if (devices.getId().equals(outbound.getDevicesId())) {
                    // 产品相同,则开始计算入库价格,出库价格,入库数量,出库数量,利润计算,直接把产品现价当做入库价格
                    reportVo.setTwoCount(reportVo.getTwoCount() + outbound.getCount());
                    ley = ley + outbound.getCount();
                    // 出库平均价
                    reportVo.setTwoPrice(reportVo.getTwoPrice()
                            .add(outbound.getPrice().multiply(new BigDecimal(outbound.getCount()))));
                    // 计算利润,使用现有出库数量*价格求和,然后通过出库数量*价格求和,然后求和,得出利润
                    twosPrice = twosPrice.add(outbound.getPrice().multiply(new BigDecimal(outbound.getCount())));
                }
            }

            // for (DevicesOutbound outbound : devicesOutbounds) {
            // //如果一样那么就是同一个产品
            // if (devices.getId().equals(outbound.getDevicesId())){
            // //产品相同,则开始计算入库价格,出库价格,入库数量,出库数量,利润计算,直接把产品现价当做入库价格
            // reportVo.setTwoCount(reportVo.getTwoCount()+outbound.getCount());
            // reportVo.setTwoPrice(outbound.getPrice());
            // //计算利润,使用现有出库数量*价格求和,然后通过出库数量*价格求和,然后求和,得出利润
            // twosPrice = twosPrice.add(outbound.getPrice().multiply(new
            // BigDecimal(outbound.getCount())));
            // }
            // }
            // 使用价格除以ley
            if (ley > 0) {
                reportVo.setTwoPrice(reportVo.getTwoPrice().divide(new BigDecimal(ley), 2, RoundingMode.HALF_UP));
            }
            if (devicesOutbounds.size() <= 0) {
                reportVo.setTwoCount(0.0f);
                reportVo.setTwoPrice(new BigDecimal("0"));
            }
            // 计算利润twosPrice减去onesPrice
            reportVo.setProfit(twosPrice.subtract(onesPrice));
            billingReportVoList.add(reportVo);
        }
        BillingReportPageVo billingReportPageVo = new BillingReportPageVo();
        billingReportPageVo.setTotal(Long.valueOf(billingReportVoList.size()));
        billingReportPageVo.setDevicesInfoVoList(billingReportVoList);

        return Result.success(billingReportPageVo);
    }

    /**
     * 通过产品名称,型号来查询出入库报表
     * 
     * @param name
     * @return
     */
    @Override
    public Result selectOutboundLike(String name) {
        // 还未做权限
        // 先查询仓库产品
        LambdaQueryWrapper<Devices> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Devices::getIsProduct, "1");
        if (name != null || !name.equals("")) {
            queryWrapper.like(Devices::getModel, name).or().like(Devices::getPartName, name);
        }
        List<Devices> devicesList = devicesMapper.selectList(queryWrapper);
        if (devicesList.size() <= 0) {
            return Result.success(new BillingReportPageVo());
        }
        List<String> devicesListId = devicesList.stream().map(Devices::getId).collect(Collectors.toList());
        // 通过产品id去查询入库单
        List<String> devicesIdListt = devicesList.stream().map(Devices::getId).collect(Collectors.toList());

        LambdaQueryWrapper<PurchaseReceipts> queryWrapper2 = new LambdaQueryWrapper<>();
        // 入库状态是已入库,并且是零件
        queryWrapper2.eq(PurchaseReceipts::getReceiptsStatus, "0");
        queryWrapper2.eq(PurchaseReceipts::getIsProduct, "1");
        queryWrapper2.in(PurchaseReceipts::getWarehouseDevId, devicesIdListt);
        List<PurchaseReceipts> receiptsList = purchaseReceiptsMapper.selectList(queryWrapper2);

        List<String> devicesIdList = receiptsList.stream().map(PurchaseReceipts::getWarehouseDevId)
                .collect(Collectors.toList());
        // 去重
        devicesIdList = devicesIdList.stream().distinct().collect(Collectors.toList());
        // 零件信息
        LambdaQueryWrapper<Devices> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(Devices::getIsProduct, "1");
        wrapper1.in(Devices::getId, devicesIdList);
        devicesList = devicesMapper.selectList(wrapper1);
        // 然后拿出所有产品id,并且去重
        if (receiptsList.size() <= 0) {
            return Result.success(new BillingReportPageVo());
        }
        // TODO 通过零件id去查询零件产品表 (可能出现的问题是这个零件id,产品表中并没有出库)
        // 拿零件id去查询出库单
        // (还有一个问题没有考虑,这个产品可能有多次出库,多次出库价格如果不一样,应该把所以相同产品,数量*价格,然后求和,得出当前产品出库收益)
        LambdaQueryWrapper<DevicesOutbound> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DevicesOutbound::getStatus, "0");
        wrapper.in(DevicesOutbound::getDevicesId, devicesListId);
        // 查询到的出库记录表
        List<DevicesOutbound> devicesOutbounds = devicesOutboundMapper.selectList(wrapper);
        // 通过产品去查询出库单
        List<BillingReportVo> billingReportVoList = new ArrayList<>();
        for (Devices devices : devicesList) {
            BillingReportVo reportVo = new BillingReportVo();
            reportVo.setTwoCount(0.0f);
            reportVo.setPartName(devices.getPartName());
            reportVo.setOnePrice(new BigDecimal("0"));
            reportVo.setTwoPrice(new BigDecimal("0"));
            reportVo.setOneCount(0.0f);
            // 入库价格
            BigDecimal twosPrice2 = new BigDecimal("0");
            Float ley2 = 0.0f;
            for (PurchaseReceipts receipts : receiptsList) {
                if (devices.getId().equals(receipts.getWarehouseDevId())) {
                    // 计算平均入库价格
                    // 产品相同,则开始计算入库价格,出库价格,入库数量,出库数量,利润计算,直接把产品现价当做入库价
                    ley2 = ley2 + receipts.getNumber();
                    // 出库平均价
                    // reportVo.setTwoPrice(outbound.getPrice());
                    reportVo.setOnePrice(reportVo.getOnePrice()
                            .add(receipts.getPrice().multiply(new BigDecimal(receipts.getNumber()))));
                    reportVo.setOneCount(reportVo.getOneCount() + receipts.getNumber());
                    // 无障碍悬浮打开之后,点击软件会直接退出,退出的时候马上再次点击软件就可以了
                }
            }
            // 使用价格除以ley
            if (ley2 > 0) {
                reportVo.setOnePrice(reportVo.getOnePrice().divide(new BigDecimal(ley2), 2, RoundingMode.HALF_UP));
            }
            reportVo.setDevicesId(devices.getId());
            reportVo.setModel(devices.getModel());
            reportVo.setImage(devices.getImage());
            BigDecimal onesPrice = reportVo.getOnePrice().multiply(new BigDecimal(reportVo.getOneCount()));
            BigDecimal twosPrice = new BigDecimal("0");
            Float ley = 0.0f;
            for (DevicesOutbound outbound : devicesOutbounds) {
                // 如果一样那么就是同一个产品
                if (devices.getId().equals(outbound.getDevicesId())) {
                    // 产品相同,则开始计算入库价格,出库价格,入库数量,出库数量,利润计算,直接把产品现价当做入库价格
                    reportVo.setTwoCount(reportVo.getTwoCount() + outbound.getCount());
                    ley = ley + outbound.getCount();
                    // 出库平均价
                    // reportVo.setTwoPrice(outbound.getPrice());
                    reportVo.setTwoPrice(reportVo.getTwoPrice()
                            .add(outbound.getPrice().multiply(new BigDecimal(outbound.getCount()))));
                    // 计算利润,使用现有出库数量*价格求和,然后通过出库数量*价格求和,然后求和,得出利润
                    twosPrice = twosPrice.add(outbound.getPrice().multiply(new BigDecimal(outbound.getCount())));
                }
            }
            // 使用价格除以ley
            if (ley > 0) {
                reportVo.setTwoPrice(reportVo.getTwoPrice().divide(new BigDecimal(ley), 2, RoundingMode.HALF_UP));
            }
            if (devicesOutbounds.size() <= 0) {
                reportVo.setTwoCount(0.0f);
                reportVo.setTwoPrice(new BigDecimal("0"));
            }
            // 计算利润twosPrice减去onesPrice
            reportVo.setProfit(twosPrice.subtract(onesPrice));
            billingReportVoList.add(reportVo);
        }
        BillingReportPageVo billingReportPageVo = new BillingReportPageVo();
        billingReportPageVo.setTotal(Long.valueOf(billingReportVoList.size()));
        billingReportPageVo.setDevicesInfoVoList(billingReportVoList);

        return Result.success(billingReportPageVo);
    }

    @Override
    public Result getDeviceList(DevicesDto devicesDto) {
        if (devicesDto == null ||
                (devicesDto.getCurrentPage() == null || devicesDto.getPageSize() == null)) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        Page<Devices> devicesPage = new Page<>(devicesDto.getCurrentPage(), devicesDto.getPageSize());
        // 条件查询
        LambdaQueryWrapper<Devices> devicesLQW = new LambdaQueryWrapper<>();
        devicesLQW.orderByDesc(Devices::getCreateTime);
        // 根据产品类型查询，0成品，1零件
        if (devicesDto.getIsProduct() != null) {
            devicesLQW.eq(Devices::getIsProduct, devicesDto.getIsProduct());
        }
        if (devicesDto.getWarehouseType() != null) {
            devicesLQW.eq(Devices::getWarehouseType, devicesDto.getWarehouseType());
        }
        // 根据名称或者型号查询
        if (devicesDto.getPartName() != null && !devicesDto.getPartName().isEmpty()) {
            devicesLQW.and(i -> i.like(Devices::getPartName, devicesDto.getPartName())
                    .or().like(Devices::getModel, devicesDto.getPartName()));
        }
        List<Devices> devicesList = devicesMapper.selectPage(devicesPage, devicesLQW).getRecords();

        Map<String, Object> map = new HashMap<>();
        map.put("total", devicesPage.getTotal());
        map.put("devicesList", devicesList);
        return Result.success("查询成功", map);
    }

    @Override
    public Result getDevice(DevicesDto devicesDto) {
        if (devicesDto == null || devicesDto.getId() == null || devicesDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        Devices devices = devicesMapper.selectById(devicesDto.getId());
        if (devices == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该产品不存在");
        }

        DevicesVo devicesVo = new DevicesVo();
        BeanUtils.copyProperties(devices, devicesVo);

        if (devices.getIsProduct() != 1) {
            // 产品为成品，查询成品零件表
            LambdaQueryWrapper<ProductPart> productPartLQW = new LambdaQueryWrapper<>();
            productPartLQW.eq(ProductPart::getDevicesId, devices.getId());
            List<ProductPart> productPartList = productPartMapper.selectList(productPartLQW);
            List<ProductPartVo> productPartVoList = new ArrayList<>();
            if (productPartList.size() > 0) {
                // 查询零件信息
                List<String> partIdList = productPartList.stream().map(ProductPart::getPartId)
                        .collect(Collectors.toList());
                List<Devices> devicesList = devicesMapper.selectBatchByIdWithDelete(partIdList);
                Map<String, Devices> devicesMap = devicesList.stream()
                        .collect(Collectors.toMap(Devices::getId, d -> devicesList.stream()
                                .filter(item -> item.getId().equals(d.getId()))
                                .findFirst()
                                .orElse(null)));
                for (ProductPart productPart : productPartList) {
                    Devices part = devicesMap.get(productPart.getPartId());
                    ProductPartVo productPartVo = new ProductPartVo();
                    productPartVo.setId(productPart.getId());
                    productPartVo.setDevicesId(devices.getId());
                    productPartVo.setPartId(productPart.getPartId());
                    productPartVo.setNumber(productPart.getNumber());
                    productPartVo.setPartName(part.getPartName());
                    productPartVo.setModel(part.getModel());
                    productPartVo.setCount(part.getCount());
                    productPartVo.setImage(part.getImage());
                    productPartVo.setDevicesDescribe(part.getDevicesDescribe());
                    productPartVoList.add(productPartVo);
                }
            }
            devicesVo.setProductPartVoList(productPartVoList);
        }
        return Result.success("查询成功", devicesVo);
    }

    @Override
    @Transactional
    public Result addDevice(DevicesDto devicesDto) {
        if (devicesDto == null || devicesDto.getPartName() == null || devicesDto.getModel() == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查权限，只有管理员和库管有权
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        boolean root = user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString()) ||
                user.getRoleId().equals(RoleEnum.ROLE_4.getCodeToString());
        if (!root) {
            return new Result(HttpStatus.FORBIDDEN, "权限不足");
        }
        Devices devices = new Devices();
        BeanUtils.copyProperties(devicesDto, devices);
        // 插入数据
        devicesMapper.insert(devices);
        if (!devicesDto.getProductPartList().isEmpty()) {
            List<ProductPart> productPartList = devicesDto.getProductPartList();
            // 查产品表
            List<String> partIdList = productPartList.stream().map(ProductPart::getPartId).collect(Collectors.toList());
            List<Devices> devicesList = devicesMapper.selectBatchByIdWithDelete(partIdList);
            // 根据partId获取Devices
            Map<String, Devices> devicesMap = devicesList.stream()
                    .collect(Collectors.toMap(Devices::getId, Function.identity()));
            BigDecimal cost = new BigDecimal(0);
            for (ProductPart productPart : productPartList) {
                Devices part = devicesMap.get(productPart.getPartId());
                BigDecimal multiply = part.getCost().multiply(new BigDecimal(productPart.getNumber()));
                cost = cost.add(multiply);
                productPart.setId(UUID.randomUUID().toString().replace("-", ""));
                productPart.setDevicesId(devices.getId());
                productPart.setCreateTime(new Date());
                productPart.setUpdateTime(new Date());
            }
            devices.setCost(cost);
            // 更新产品成本价
            devicesMapper.updateById(devices);
            productPartMapper.insertBatch(devicesDto.getProductPartList());
        }
        return Result.success("添加成功");
    }

    @Override
    @Transactional
    public Result updateDevice(DevicesDto devicesDto) {
        if (devicesDto == null || devicesDto.getId() == null || devicesDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查权限，只有管理员和库管有权
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        boolean root = user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString()) ||
                user.getRoleId().equals(RoleEnum.ROLE_4.getCodeToString());
        if (!root) {
            return new Result(HttpStatus.FORBIDDEN, "权限不足");
        }
        // 查询是否有该产品
        Devices devices = devicesMapper.selectById(devicesDto.getId());
        if (devices == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该产品不存在");
        }
        // 更新数据
        BigDecimal oldCost = devices.getCost();
        BeanUtils.copyProperties(devicesDto, devices);
        if (devicesDto.getIsUpdatePartList() == 1) {
            // 产品为成品，修改成品零件列表
            // 删除成品零件列表
            productPartMapper.deleteByDevicesId(devices.getId());
            // 再插入新的列表
            if (!devicesDto.getProductPartList().isEmpty()) {
                List<ProductPart> productPartList = devicesDto.getProductPartList();
                // 查产品表
                List<String> partIdList = productPartList.stream().map(ProductPart::getPartId)
                        .collect(Collectors.toList());
                List<Devices> devicesList = devicesMapper.selectBatchByIdWithDelete(partIdList);
                // 根据partId获取Devices
                Map<String, Devices> devicesMap = devicesList.stream()
                        .collect(Collectors.toMap(Devices::getId, Function.identity()));
                BigDecimal cost = new BigDecimal(0);
                for (ProductPart productPart : productPartList) {
                    Devices part = devicesMap.get(productPart.getPartId());
                    BigDecimal multiply = part.getCost().multiply(new BigDecimal(productPart.getNumber()));
                    cost = cost.add(multiply);
                    productPart.setId(UUID.randomUUID().toString().replace("-", ""));
                    productPart.setDevicesId(devices.getId());
                    productPart.setCreateTime(new Date());
                    productPart.setUpdateTime(new Date());
                }
                devices.setCost(cost);
                productPartMapper.insertBatch(devicesDto.getProductPartList());
            }
        }
        devicesMapper.updateById(devices);
        if (devices.getIsProduct() == 1) {
            // 产品为零件，判断采购单价是否变化
            if (!devicesDto.getCost().equals(oldCost)) {
                // 零件的采购单价改变
                Set<String> devicesIdList = new HashSet<>();
                devicesIdList.add(devices.getId());
                normalTask.updateProductPrice(devicesIdList);
            }
        }
        return Result.success("修改成功");
    }

    @Override
    public Result deleteDevice(DevicesDto devicesDto) {
        if (devicesDto == null || devicesDto.getId() == null || devicesDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查权限，只有管理员有权
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        if (!user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString())) {
            return new Result(HttpStatus.FORBIDDEN, "权限不足");
        }

        // 查询是否有该产品
        Devices devices = devicesMapper.selectById(devicesDto.getId());
        if (devices == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该产品不存在");
        }
        // 删除
        devicesMapper.deleteById(devices.getId());
        if (devices.getIsProduct() == 0) {
            // 删除产品零件
            LambdaQueryWrapper<ProductPart> productPartLQW = new LambdaQueryWrapper<>();
            productPartLQW.eq(ProductPart::getDevicesId, devices.getId());
            productPartMapper.delete(productPartLQW);
        }
        return Result.success("删除成功");
    }

    @Override
    @Transactional
    public Result assembleDevice(DevicesDto devicesDto) {
        if (devicesDto == null || devicesDto.getId() == null || devicesDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查权限，只有管理员和库管有权
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        boolean root = user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString()) ||
                user.getRoleId().equals(RoleEnum.ROLE_4.getCodeToString());
        if (!root) {
            return new Result(HttpStatus.FORBIDDEN, "权限不足");
        }
        // 查询是否拥有该成品
        Devices devices = devicesMapper.selectById(devicesDto.getId());
        if (devices == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该产品不存在");
        }
        // 查该成品的零件列表
        LambdaQueryWrapper<ProductPart> productPartLQW = new LambdaQueryWrapper<>();
        productPartLQW.eq(ProductPart::getDevicesId, devices.getId());
        List<ProductPart> productPartList = productPartMapper.selectList(productPartLQW);
        if (productPartList.size() > 0) {
            // 查询零件信息
            List<String> parIdList = productPartList.stream().map(ProductPart::getPartId).collect(Collectors.toList());
            List<Devices> partList = devicesMapper.selectBatchIds(parIdList);
            Map<String, Devices> partMap = partList.stream()
                    .collect(Collectors.toMap(Devices::getId, d -> partList.stream()
                            .filter(part -> part.getId().equals(d.getId()))
                            .findFirst()
                            .orElse(null)));
            // 开始组装，先减去库存，若库存足够，则成品数量增加
            List<Devices> newPartList = new ArrayList<>(); // 新的库存零件集合
            for (ProductPart part : productPartList) {
                Devices inventoryPart = partMap.get(part.getPartId());
                // 消耗零件数量=组装数量*成品数量
                float expend = part.getNumber() * devicesDto.getProductCount();
                // 判断库存是否充足，库存-消耗
                float lack = inventoryPart.getCount() - expend;
                if (lack < 0) {
                    return new Result(HttpStatus.BAD_REQUEST, "零件库存不足");
                }
                // 更新库存
                inventoryPart.setCount(lack);
                newPartList.add(inventoryPart);
            }
            // 更新零件库存
            devicesMapper.updateCountBatchById(newPartList);
        }
        devices.setCount(devices.getCount() + devicesDto.getProductCount());
        // 更新成品库存数量
        LambdaUpdateWrapper<Devices> devicesLUW = new LambdaUpdateWrapper<>();
        devicesLUW.eq(Devices::getId, devices.getId()).set(Devices::getCount, devices.getCount());
        devicesMapper.update(null, devicesLUW);
        return Result.success("操作成功");
    }

    @Override
    @Transactional
    public Result dismantleDevice(DevicesDto devicesDto) {
        if (devicesDto.getId() == null || devicesDto.getId().isEmpty()) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        // 查权限，只有管理员和库管有权
        User user = userMapper.selectById(StpUtil.getLoginIdAsString());
        boolean root = user.getRoleId().equals(RoleEnum.ROLE_1.getCodeToString()) ||
                user.getRoleId().equals(RoleEnum.ROLE_4.getCodeToString());
        if (!root) {
            return new Result(HttpStatus.FORBIDDEN, "权限不足");
        }
        // 查询是否有该成品
        Devices devices = devicesMapper.selectById(devicesDto.getId());
        if (devices == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该产品不存在");
        }
        // 拆解数量大于成品库存数量
        if (devicesDto.getProductCount() > devices.getCount()) {
            return new Result(HttpStatus.BAD_REQUEST, "拆解数量大于库存数量");
        }
        // 查该成品的零件列表
        LambdaQueryWrapper<ProductPart> productPartLQW = new LambdaQueryWrapper<>();
        productPartLQW.eq(ProductPart::getDevicesId, devices.getId());
        List<ProductPart> productPartList = productPartMapper.selectList(productPartLQW);
        if (productPartList.size() > 0) {
            // 查询零件信息
            List<String> parIdList = productPartList.stream().map(ProductPart::getPartId).collect(Collectors.toList());
            List<Devices> partList = devicesMapper.selectBatchIds(parIdList);
            Map<String, Devices> partMap = partList.stream()
                    .collect(Collectors.toMap(Devices::getId, d -> partList.stream()
                            .filter(part -> part.getId().equals(d.getId()))
                            .findFirst()
                            .orElse(null)));
            // 开始拆解
            List<Devices> newPartList = new ArrayList<>(); // 新的库存零件集合
            for (ProductPart part : productPartList) {
                Devices inventoryPart = partMap.get(part.getPartId());
                // 拆解出来的零件数=组装数量*拆解数量
                float expend = part.getNumber() * devicesDto.getProductCount();
                // 加上拆解出来的数量
                float lack = inventoryPart.getCount() + expend;
                // 更新库存
                inventoryPart.setCount(lack);
                newPartList.add(inventoryPart);
            }
            // 更新零件库存
            devicesMapper.updateCountBatchById(newPartList);
        }
        devices.setCount(devices.getCount() - devicesDto.getProductCount());
        // 更新成品库存数量
        LambdaUpdateWrapper<Devices> devicesLUW = new LambdaUpdateWrapper<>();
        devicesLUW.eq(Devices::getId, devices.getId()).set(Devices::getCount, devices.getCount());
        devicesMapper.update(null, devicesLUW);
        return Result.success("操作成功");
    }

    @Override
    public Result calculateAssembleDevice() {
        // 查询所有的成品
        Set<DevicesVo> devicesVoList = new HashSet<>();
        Set<DevicesVo> devicesPartVoList = new HashSet<>();
        LambdaQueryWrapper<Devices> devicesLQW = new LambdaQueryWrapper<>();
        devicesLQW.orderByDesc(Devices::getCreateTime).eq(Devices::getIsProduct, 0);
        List<Devices> devicesList = devicesMapper.selectList(devicesLQW);
        Map<String, Set<DevicesVo>> map = new HashMap<>();
        if (devicesList.isEmpty()) {
            map.put("devicesVoList", devicesVoList);
            map.put("devicesPartVoList", devicesPartVoList);
            return Result.success("查询成功", map);
        }

        // 查询成品所有的组成零件
        // 获取所有成品的id
        List<String> devicesIdList = devicesList.stream().map(Devices::getId).collect(Collectors.toList());
        // 根据成品id查询成品零件表
        LambdaQueryWrapper<ProductPart> productPartLQW = new LambdaQueryWrapper<>();
        productPartLQW.in(ProductPart::getDevicesId, devicesIdList);
        List<ProductPart> productPartList = productPartMapper.selectList(productPartLQW);
        if (productPartList.isEmpty()) {
            // 成品零件列表为空，没必要计算，直接返回结果;
            map.put("devicesVoList", devicesVoList);
            map.put("devicesPartVoList", devicesPartVoList);
            return Result.success("查询成功", map);
        }
        // 处理成map集合，通过成品id拿到对应的零件集合
        Map<String, List<ProductPart>> productPartMap = new HashMap<>();
        for (ProductPart productPart : productPartList) {
            if (productPartMap.containsKey(productPart.getDevicesId())) {
                // 判断是否有该成品id的key，有就往零件集合中添加零件
                productPartMap.get(productPart.getDevicesId()).add(productPart);
            } else {
                // 没有就put
                List<ProductPart> PartList = new ArrayList<>();
                PartList.add(productPart);
                productPartMap.put(productPart.getDevicesId(), PartList);
            }
        }

        // 查零件集合
        Set<String> partIdList = productPartList.stream().map(ProductPart::getPartId).collect(Collectors.toSet());
        List<Devices> partList = devicesMapper.selectBatchByIdWithDelete(partIdList);
        if (partList.size() > 0) {
            for (Devices part : partList) {
                DevicesVo partVo = new DevicesVo();
                BeanUtils.copyProperties(part, partVo);
                partVo.setExpendTotal(0.0f);
                partVo.setLackTotal(0.0f);
                devicesPartVoList.add(partVo);
            }
        }
        // 将零件集合处理成map集合
        Map<String, Devices> partMap = partList.stream().collect(Collectors.toMap(Devices::getId, d -> partList.stream()
                .filter(part -> part.getId().equals(d.getId()))
                .findFirst()
                .orElse(null)));
        Map<String, DevicesVo> partVoMap = devicesPartVoList.stream()
                .collect(Collectors.toMap(DevicesVo::getId, d -> devicesPartVoList.stream()
                        .filter(partVo -> partVo.getId().equals(d.getId()))
                        .findFirst()
                        .orElse(null)));

        // 查询百分比组装程度
        Current current = currentMapper.selectById(1);
        // 开始计算组装
        // 临时存储零件库存数量的map，用于计算组装
        Map<String, Float> inventoryMap = partList.stream()
                .collect(Collectors.toMap(Devices::getId, Devices::getCount));
        for (Devices devices : devicesList) {
            DevicesVo devicesVo = new DevicesVo();
            BeanUtils.copyProperties(devices, devicesVo);
            // 能够组装成品的最大数量
            int productCount = 0;
            List<ProductPartVo> partVoList = new ArrayList<>();

            // 组装成品的零件集合
            List<ProductPart> parts = new ArrayList<>();
            if (productPartMap.containsKey(devices.getId())) {
                parts = productPartMap.get(devices.getId());
            }
            // 组装成品的总零件数
            int partCourt = parts.size();
            if (parts.isEmpty()) {
                // 组装成品的零件集合为空，直接跳过
                devicesVo.setProductPartVoList(partVoList);
                devicesVo.setCountMax(productCount);
                devicesVoList.add(devicesVo);
                continue;
            }
            // 根据百分比计算需要足够库存的零件数量，组装程度=（足够库存的零件数/总零件数）*100%
            // 足够库存的零件数=(组装程度*总零件数)/100%
            double result = (double) (current.getCourt() * partCourt) / 100;
            if (result < 1.0 && result > 0.0) {
                result = 1.0;
            }
            int adequate = (int) result;

            // 库存充足的最大零件数量
            int adequateMax = adequate;
            while (adequateMax >= adequate) {
                adequateMax = 0;
                // 临时储存库存剩余数量
                Map<String, Float> surplusMap = new HashMap<>();
                for (ProductPart productPart : parts) {
                    if (adequateMax >= adequate) {
                        // 如果本轮while循环中，库存充足的最大零件数量已经等于足够库存的零件数
                        // 那就结束for循环，进入下一轮while循环
                        break;
                    }
                    Devices part = partMap.get(productPart.getPartId());
                    // 库存剩余数量=临时库存数量-组装数量
                    float surplus = inventoryMap.get(part.getId()) - productPart.getNumber();
                    if (surplus < 0) {
                        // 库存剩余数量小于0，开始下一次for循环
                        continue;
                    }
                    // 放入临时存储库存剩余数量的map
                    surplusMap.put(part.getId(), surplus);
                    // 库存充足的最大零件数量加1
                    adequateMax++;
                }
                if (adequateMax >= adequate) {
                    // 更新临时库存数量
                    for (ProductPart productPart : parts) {
                        Devices part = partMap.get(productPart.getPartId());
                        if (surplusMap.containsKey(part.getId())) {
                            inventoryMap.put(part.getId(), surplusMap.get(part.getId()));
                        }
                    }
                    // 成品组装数量加1
                    productCount++;
                }
            }

            // 重置临时库存数量
            inventoryMap = partList.stream().collect(Collectors.toMap(Devices::getId, Devices::getCount));
            // 计算零件缺少数量
            // 计算零件总消耗数，总缺少数
            for (ProductPart productPart : parts) {
                Devices part = partMap.get(productPart.getPartId());
                ProductPartVo productPartVo = new ProductPartVo();
                BeanUtils.copyProperties(productPart, productPartVo);
                productPartVo.setPartName(part.getPartName());
                productPartVo.setModel(part.getModel());
                productPartVo.setCount(part.getCount());
                productPartVo.setImage(part.getImage());
                // 组装成品消耗数量，组装数量*成品组装数量
                productPartVo.setExpend(productPart.getNumber() * productCount);
                // 总消耗数量累加
                DevicesVo partVo = partVoMap.get(part.getId());
                partVo.setExpendTotal(partVo.getExpendTotal() + productPartVo.getExpend());
                // 库存剩余数量，临时库存-消耗数量
                float surplus = inventoryMap.get(part.getId()) - productPartVo.getExpend();
                if (surplus < 0) {
                    // 库存剩余数量为负数
                    // 设置缺少零件数，乘以-1
                    productPartVo.setLack(surplus * (-1));
                    // 总缺少零件增加
                    partVo.setLackTotal(partVo.getLackTotal() + productPartVo.getLack());
                    // 更新临时库存库存剩余数量为0;
                    inventoryMap.put(part.getId(), 0.0f);
                } else {
                    // 库存剩余数量不为负数
                    // 设置缺少零件数为0
                    productPartVo.setLack(0.0f);
                    // 更新库存剩余数量
                    inventoryMap.put(part.getId(), surplus);
                }
                partVoList.add(productPartVo);
            }
            devicesVo.setProductPartVoList(partVoList);
            devicesVo.setCountMax(productCount);
            devicesVoList.add(devicesVo);
        }
        map.put("devicesVoList", devicesVoList);
        map.put("devicesPartVoList", devicesPartVoList);
        return Result.success("查询成功", map);
    }

    @Override
    public Result changeDeviceImg(DevicesDto devicesDto) {
        if (devicesDto == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        if (devicesDto.getId() == null) {
            return new Result(HttpStatus.BAD_REQUEST, "缺少参数");
        }
        Devices devices = devicesMapper.selectById(devicesDto.getId());
        if (devices == null) {
            return new Result(HttpStatus.BAD_REQUEST, "该产品不存在");
        }
        // 修改
        devices.setImage(devicesDto.getImage());
        LambdaUpdateWrapper<Devices> devicesLUW = new LambdaUpdateWrapper<>();
        devicesLUW.eq(Devices::getId, devices.getId()).set(Devices::getImage, devices.getImage());
        devicesMapper.update(null, devicesLUW);
        return Result.success("修改成功");
    }
}
